
using Unity.Burst;
using Unity.Collections;
using Unity.Mathematics;




[BurstCompile]
public struct MapData
{
    private NativeArray<half> heightMapData;

    private int size;

    private float heightScale;  //   实际地图和记录高度缩放比
    
    private float mapToWorldScale;     //   地图和高度图的缩放比  pos/mapScale = pos/size 


    public float GetHeightData(int2 pos)
    {
        return GetHeightData(pos.x, pos.y)*heightScale;
    }
    public half GetHeightData(int x, int y)
    {
        int index = GetIndex(x, y);
        if(index>heightMapData.Length) return half.zero;
        
        return heightMapData[index];
    }

    public void SetHeightData(int x, int y, half height)
    {
        int index = GetIndex(x, y);
        if(index>heightMapData.Length) return;
        
        heightMapData[index] = height;
    }


    private int GetIndex(int2 pos)
    { 
        return GetIndex(pos.x, pos.y);
    }
    private int GetIndex(int x, int y)
    {
        
         return y * size + x;
    }

    public bool CheckPointVisible(float3 checkPoint,float3 camPos)
    {

        float3 dir = math.normalize(camPos - checkPoint);

        //按道来说应该step到超出采样范围或者得到遮挡结果
        
        for (int i = 1; i < size; i++)
        {
            float3 pos = dir * mapToWorldScale * i;
            int2 mapIndex = WorldPosToMapIndex(pos.xz);

            // 判断是否超出读取区域范围

            if (OutOfBound(mapIndex.x, mapIndex.y))
            {
                return true;
            }
            
            float height = GetHeightData(mapIndex);

            if (height > pos.y) return false;           //采样得出数值比当前步进视距点高度要高 为遮挡状态

        }
        
        
        
        return true;


    }


    // 需要 center 中心点偏移 scale 地图距离比缩放 处理
    private int2 WorldPosToMapIndex(float2 worldPos)
    {
        return (int2)worldPos.xy;
    }
    
    
    


    /// <summary>
    /// 判断是否超出读取区域范围
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    private bool OutOfBound(int x,int y)
    {
        if (x < 0 || y < 0) return true;
        if (x > size || y > size) return true;
        return false;
    }

}